package changceilingcolor003;

import processing.core.PApplet;
import toxi.geom.Vec3D;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;

import org.w3c.dom.*;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

public class Environment {

	ChangCeilingColor003 p5;

	String [] origins1;
	String [] origins2;
	String [] origins3;
	String [] boundries1;
	String [] boundries2;
	String [] boundries3;
	String [] distraction;

	Environment(ChangCeilingColor003 _p5) {
		p5=_p5;
		Origins();		
		Boundries();
		Distractions();
	}
	//
	void run() 
	{
		buildBox(p5.width, p5.height, 120);

		for (int i=0;i<p5.alisOrigin1.size();i++) 
		{
			Vec3D v=(Vec3D)p5.alisOrigin1.get(i);
			p5.stroke(235);
			p5.strokeWeight(3);
			//p5.point(v.x, v.y, v.z);
			p5.strokeWeight(1);
			//p5.line(v.x, v.y+5, v.x, v.y-5);
			p5.stroke(255,0,0,80);
			p5.strokeWeight(1);
			//p5.rect(v.x, v.y+15,5,15);
			//p5.line(v.x, v.y+15, v.x+15, v.y+15);
			p5.rect(v.x-7, v.y+5,15,15);

		}

		for (int i=0;i<p5.alisOrigin2.size();i++) 
		{
			Vec3D v=(Vec3D)p5.alisOrigin2.get(i);
			p5.stroke(235);
			p5.strokeWeight(3);
			//p5.point(v.x, v.y, v.z);
			p5.strokeWeight(1);
			//p5.line(v.x+5, v.y, v.x-5, v.y);
			p5.stroke(255,0,0,80);
			p5.strokeWeight(1);
			//p5.rect(v.x+15, v.y,15,5);
			p5.rect(v.x+5, v.y-20,15,15);
		}

		for (int i=0;i<p5.alisOrigin3.size();i++) 
		{
			Vec3D v=(Vec3D)p5.alisOrigin3.get(i);
			p5.stroke(235);
			p5.strokeWeight(3);
			//p5.point(v.x, v.y, v.z);
			p5.strokeWeight(1);
			//p5.line(v.x, v.y+5, v.x, v.y-5);
			p5.stroke(255,0,0,80);
			p5.strokeWeight(1);
			//p5.rect(v.x, v.y-30,5,15);
			p5.rect(v.x-7, v.y-20,15,15);
		}

		//boundries
		if(p5.showBoundary)
		{
			for (int i=0;i<p5.alisBnd1.size();i++) {
				Vec3D v=(Vec3D)p5.alisBnd1.get(i);
				//Vec3D u=(Vec3D)p5.alisBnd1.get(i+1);
				p5.stroke(255);
				p5.strokeWeight(2);
				//p5.line(v.x, v.y, u.x, u.y);
				p5.point(v.x, v.y, v.z);
			}

			for (int i=0;i<p5.alisBnd2.size();i++) {
				Vec3D v=(Vec3D)p5.alisBnd2.get(i);
				p5.stroke(255,90);
				p5.strokeWeight(2);
				p5.point(v.x, v.y, v.z);
			}

			for (int i=0;i<p5.alisBnd3.size();i++) {
				Vec3D v=(Vec3D)p5.alisBnd3.get(i);
				p5.stroke(100,20);
				p5.strokeWeight(1);
				p5.point(v.x, v.y, v.z);
			}


		}
		//

	}


	void Origins() {
		origins1 =p5.loadStrings("data/ORG1.txt"); 
		for (int i= 0; i <origins1.length; i++) {  
			String [] fields = PApplet.split(origins1[i], ',');
			float x = Float.valueOf(fields[0]);
			float y = Float.valueOf(fields[1]);
			float z = Float.valueOf(fields[2]);
			Vec3D v = new Vec3D (x, y, z);
			p5.alisOrigin1.add(v);
			p5.alisOrigin.add(v);
		}

		origins2 =p5.loadStrings("data/ORG2.txt"); 
		for (int i= 0; i <origins2.length; i++) {  
			String [] fields = PApplet.split(origins2[i], ',');
			float x = Float.valueOf(fields[0]);
			float y = Float.valueOf(fields[1]);
			float z = Float.valueOf(fields[2]);
			Vec3D v = new Vec3D (x, y, z);
			p5.alisOrigin2.add(v);
			p5.alisOrigin.add(v);
		}

		origins3 =p5.loadStrings("data/ORG3.txt"); 
		for (int i= 0; i <origins3.length; i++) {  
			String [] fields = PApplet.split(origins3[i], ',');
			float x = Float.valueOf(fields[0]);
			float y = Float.valueOf(fields[1]);
			float z = Float.valueOf(fields[2]);
			Vec3D v = new Vec3D (x, y, z);
			p5.alisOrigin3.add(v);
			p5.alisOrigin.add(v);
		}

	}

	void Boundries() {
		boundries1 =p5.loadStrings("data/BND1.txt"); 
		for (int i= 0; i <boundries1.length; i++) {  
			String [] fields = PApplet.split(boundries1[i], ',');
			float x = Float.valueOf(fields[0]);
			float y = Float.valueOf(fields[1]);
			float z = Float.valueOf(fields[2]);
			Vec3D v = new Vec3D (x, y, z);
			p5.alisBnd1.add(v);
		}

		boundries2 =p5.loadStrings("data/BND2.txt"); 
		for (int i= 0; i <boundries2.length; i++) {  
			String [] fields = PApplet.split(boundries2[i], ',');
			float x = Float.valueOf(fields[0]);
			float y = Float.valueOf(fields[1]);
			float z = Float.valueOf(fields[2]);
			Vec3D v = new Vec3D (x, y, z);
			p5.alisBnd2.add(v);
		}
		boundries3 =p5.loadStrings("data/BND3.txt"); 
		for (int i= 0; i <boundries3.length; i++) {  
			String [] fields = PApplet.split(boundries3[i], ',');
			float x = Float.valueOf(fields[0]);
			float y = Float.valueOf(fields[1]);
			float z = Float.valueOf(fields[2]);
			Vec3D v = new Vec3D (x, y, z);
			p5.alisBnd3.add(v);
		}		
	}

	void Distractions() {
		distraction =p5.loadStrings("data/DST.txt"); 
		for (int i= 0; i <distraction.length; i++) {  
			String [] fields = PApplet.split(distraction[i], ',');
			String ID = fields[0];
			String description = fields[1];
			float x = Float.valueOf(fields[2]);
			float y = Float.valueOf(fields[3]);
			float z = Float.valueOf(fields[4]);
			int R = Integer.parseInt( fields[5]);
			int G = Integer.parseInt( fields[6]);
			int B = Integer.parseInt( fields[7]);
			int AttractionRadious =  Integer.parseInt( fields[8]);
			int Min_X =  Integer.parseInt( fields[10]);
			int Max_X =  Integer.parseInt( fields[11]);
			int Min_Y =  Integer.parseInt( fields[12]);
			int Max_Y =  Integer.parseInt( fields[13]);
			int Min_Z =  Integer.parseInt( fields[14]);
			int Max_Z =  Integer.parseInt( fields[15]);
			int Min_R =  Integer.parseInt( fields[16]);
			int Max_R =  Integer.parseInt( fields[17]);





			
			
			
			Vec3D location = new Vec3D (Min_X + (Max_X-Min_X)/2, Min_Y + (Max_Y-Min_Y)/2, 0);
			Attraction Distration = new Attraction(p5,ID,description,R,G,B,AttractionRadious,Min_X,Max_X,Min_Y,Max_Y,Min_Z,Max_Z,Min_R,Max_R,location);					
			//Distration.SetAttractionRadious(AttractionRadious);
			p5.alisDst.add(Distration);
			p5.AttractionDictionary.put(ID, Distration);////////////////////////////////////////////////

		}
		
		ReadAttractionBoundary("data/AttractionLimit.xml");
		
		
	}

	void buildBox(float x, float y, float z) {
		p5.noFill();
		p5.stroke(235, 30);
		p5.strokeWeight(1);
		p5.pushMatrix();
		p5.translate(p5.width/2, p5.height/2, 60);
		p5.scale(x, y, z);
		p5.box(1);
		p5.popMatrix();
	}

	void ReadAttractionBoundary(String sFileName)
	{
		try {

			DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
			Document doc = docBuilder.parse (new File(sFileName));
			
			
			  // normalize text representation
            doc.getDocumentElement ().normalize ();
            
            
            NodeList listOfLimits = doc.getElementsByTagName("Limit");
            
            
            ArrayList<AttractionInteractionProperties> AttractionInteractionPropertiesHolder = new ArrayList<AttractionInteractionProperties>();                      
            
            int totalAttraction = listOfLimits.getLength();
            System.out.println("Total no of attraction : " + totalAttraction);

            for(int s=0; s<listOfLimits.getLength() ; s++){

            	Node firstAttractionNode = listOfLimits.item(s);
                if(firstAttractionNode.getNodeType() == Node.ELEMENT_NODE){

                    Element firstPersonElement = (Element)firstAttractionNode;
                    if(firstPersonElement.getAttribute("Attractor1") != null &&  firstPersonElement.getAttribute("Attractor2")!= null )
                    {
                    	
                    	Element LimitMaxDistance = (Element)firstPersonElement.getElementsByTagName("MaxDistance").item(0);
                    	Element LimitMinDistance = (Element)firstPersonElement.getElementsByTagName("MinDistance").item(0);
                    	double  max_distance = Double.parseDouble(LimitMaxDistance.getAttribute("Value") ); 
                    	double  min_distance = Double.parseDouble(LimitMinDistance.getAttribute("Value") );
                    	
                    	AttractionInteractionProperties newAttractionProperties =  new AttractionInteractionProperties(firstPersonElement.getAttribute("Attractor1"), firstPersonElement.getAttribute("Attractor2"), min_distance, max_distance);
                    	AttractionInteractionPropertiesHolder.add(newAttractionProperties);
                    }
                }//end of if clause
            }//end of for loop with s var   

            Element oElm =  (Element) doc.getElementsByTagName("AttractionConnectionPriority").item(0);
            
            NodeList listOfAttraction = oElm.getElementsByTagName("Attractor");
            
            for(int s=0; s<listOfAttraction.getLength() ; s++){
            	Element examineAttractorInfo =  (Element) listOfAttraction.item(s);            	
            	Attraction examineAttractor = p5.AttractionDictionary.get(examineAttractorInfo.getAttribute("Id"));            	
            	int nMaxConnection = Integer.parseInt(examineAttractorInfo.getAttribute("MaxConnection"));            	
            	examineAttractor.SetMaxNumberOfConnection(nMaxConnection);            	
            	NodeList attractorPriority =examineAttractorInfo.getElementsByTagName("ConnectTo"); 
            	for(int i = 0; i < attractorPriority.getLength(); ++i)
            	{
            		examineAttractor.AddAttractorToPreferdList( ((Element) attractorPriority.item(i)).getAttribute("Id"));
            	}
            }//end of for loop with s var   
            
            p5.AttractionInteractionPropertiesHolder = new AttractionInteractionHolder(AttractionInteractionPropertiesHolder);
			
		}catch (SAXParseException err) {
			System.out.println ("** Parsing error" + ", line " 
					+ err.getLineNumber () + ", uri " + err.getSystemId ());
			System.out.println(" " + err.getMessage ());

		}catch (SAXException e) {
			Exception x = e.getException ();
			((x == null) ? e : x).printStackTrace ();

		}catch (Throwable t) {
			t.printStackTrace ();
		}
		//System.exit (0);

	}

}
